//! 错误处理模块
//! 
//! 定义系统中所有可能的错误类型和错误处理机制

use thiserror::Error;

/// 系统错误类型定义
#[derive(Error, Debug, Clone)]
pub enum Error {
    /// IO错误
    #[error("IO error: {0}")]
    Io(String),
    
    /// 序列化错误
    #[error("Serialization error: {0}")]
    Serde(String),
    
    /// YAML解析错误
    #[error("YAML parse error: {0}")]
    Yaml(String),
    
    /// TOML解析错误
    #[error("TOML parse error: {0}")]
    TomlDe(String),
    
    /// TOML序列化错误
    #[error("TOML serialize error: {0}")]
    TomlSer(String),
    
    /// 配置格式错误
    #[error("Unsupported config format")]
    ConfigFormat,
    
    /// 无效配置
    #[error("Invalid configuration: {0}")]
    InvalidConfig(String),
    
    /// 沙箱创建错误
    #[error("Sandbox creation failed: {0}")]
    SandboxCreation(String),
    
    /// 沙箱启动错误
    #[error("Sandbox start failed: {0}")]
    SandboxStart(String),
    
    /// 沙箱停止错误
    #[error("Sandbox stop failed: {0}")]
    SandboxStop(String),
    
    /// 沙箱执行错误
    #[error("Sandbox execution failed: {0}")]
    SandboxExecution(String),
    
    /// 沙箱不存在
    #[error("Sandbox not found: {0}")]
    SandboxNotFound(String),
    
    /// 资源不足
    #[error("Insufficient resources: {0}")]
    InsufficientResources(String),
    
    /// 池化错误
    #[error("Pool error: {0}")]
    PoolError(String),
    
    /// 调度错误
    #[error("Scheduler error: {0}")]
    SchedulerError(String),
    
    /// 监控错误
    #[error("Monitoring error: {0}")]
    MonitoringError(String),
    
    /// 网络错误
    #[error("Network error: {0}")]
    Network(String),
    
    /// Prometheus错误
    #[error("Prometheus error: {0}")]
    Prometheus(String),
    
    /// UTF8错误
    #[error("UTF8 error: {0}")]
    Utf8(String),
    
    /// 超时错误
    #[error("Operation timed out: {0}")]
    Timeout(String),
    
    /// 权限错误
    #[error("Permission denied: {0}")]
    PermissionDenied(String),
    
    /// 系统调用错误
    #[error("System call error: {0}")]
    SystemCall(String),
    
    /// Firecracker相关错误
    #[error("Firecracker error: {0}")]
    Firecracker(String),
    
    /// 内部错误
    #[error("Internal error: {0}")]
    Internal(String),
    
    /// API错误
    #[error("API error: {0}")]
    Api(String),
    
    /// 验证错误
    #[error("Validation error: {0}")]
    Validation(String),
    
    /// 通用错误
    #[error("Error: {0}")]
    Generic(String),
}

/// 结果类型别名
pub type Result<T> = std::result::Result<T, Error>;

// 错误转换实现
impl From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Self {
        Error::Io(err.to_string())
    }
}

impl From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Self {
        Error::Serde(err.to_string())
    }
}

impl From<serde_yaml::Error> for Error {
    fn from(err: serde_yaml::Error) -> Self {
        Error::Yaml(err.to_string())
    }
}

impl From<toml::de::Error> for Error {
    fn from(err: toml::de::Error) -> Self {
        Error::TomlDe(err.to_string())
    }
}

impl From<reqwest::Error> for Error {
    fn from(err: reqwest::Error) -> Self {
        Error::Network(err.to_string())
    }
}

impl From<std::string::FromUtf8Error> for Error {
    fn from(err: std::string::FromUtf8Error) -> Self {
        Error::Utf8(err.to_string())
    }
}

impl From<anyhow::Error> for Error {
    fn from(err: anyhow::Error) -> Self {
        Error::Generic(err.to_string())
    }
}

// Prometheus错误转换
impl From<prometheus::Error> for Error {
    fn from(err: prometheus::Error) -> Self {
        Error::Prometheus(err.to_string())
    }
}

impl Error {
    /// 创建沙箱创建错误
    pub fn sandbox_creation<S: Into<String>>(msg: S) -> Self {
        Error::SandboxCreation(msg.into())
    }
    
    /// 创建沙箱启动错误
    pub fn sandbox_start<S: Into<String>>(msg: S) -> Self {
        Error::SandboxStart(msg.into())
    }
    
    /// 创建沙箱停止错误
    pub fn sandbox_stop<S: Into<String>>(msg: S) -> Self {
        Error::SandboxStop(msg.into())
    }
    
    /// 创建沙箱执行错误
    pub fn sandbox_execution<S: Into<String>>(msg: S) -> Self {
        Error::SandboxExecution(msg.into())
    }
    
    /// 创建沙箱未找到错误
    pub fn sandbox_not_found<S: Into<String>>(id: S) -> Self {
        Error::SandboxNotFound(id.into())
    }
    
    /// 创建资源不足错误
    pub fn insufficient_resources<S: Into<String>>(msg: S) -> Self {
        Error::InsufficientResources(msg.into())
    }
    
    /// 创建池化错误
    pub fn pool_error<S: Into<String>>(msg: S) -> Self {
        Error::PoolError(msg.into())
    }
    
    /// 创建调度错误
    pub fn scheduler_error<S: Into<String>>(msg: S) -> Self {
        Error::SchedulerError(msg.into())
    }
    
    /// 创建超时错误
    pub fn timeout<S: Into<String>>(msg: S) -> Self {
        Error::Timeout(msg.into())
    }
    
    /// 创建网络错误
    pub fn network<S: Into<String>>(msg: S) -> Self {
        Error::Network(msg.into())
    }
    
    /// 创建API错误
    pub fn api<S: Into<String>>(msg: S) -> Self {
        Error::Api(msg.into())
    }
    
    /// 创建验证错误
    pub fn validation<S: Into<String>>(msg: S) -> Self {
        Error::Validation(msg.into())
    }
    
    /// 创建Firecracker错误
    pub fn firecracker<S: Into<String>>(msg: S) -> Self {
        Error::Firecracker(msg.into())
    }
    
    /// 创建内部错误
    pub fn internal<S: Into<String>>(msg: S) -> Self {
        Error::Internal(msg.into())
    }
    
    /// 创建IO错误
    pub fn io_error<S: Into<String>>(msg: S) -> Self {
        Error::Internal(format!("IO Error: {}", msg.into()))
    }
    
    /// 判断是否是可重试的错误
    pub fn is_retryable(&self) -> bool {
        matches!(
            self,
            Error::Timeout(_) 
            | Error::InsufficientResources(_) 
            | Error::Network(_)
            | Error::SandboxCreation(_)
            | Error::SandboxStart(_)
        )
    }
    
    /// 获取错误代码
    pub fn error_code(&self) -> &'static str {
        match self {
            Error::Io(_) => "IO_ERROR",
            Error::Serde(_) => "SERDE_ERROR",
            Error::Yaml(_) => "YAML_ERROR",
            Error::TomlDe(_) => "TOML_DE_ERROR",
            Error::TomlSer(_) => "TOML_SER_ERROR",
            Error::ConfigFormat => "CONFIG_FORMAT_ERROR",
            Error::InvalidConfig(_) => "INVALID_CONFIG",
            Error::SandboxCreation(_) => "SANDBOX_CREATION_ERROR",
            Error::SandboxStart(_) => "SANDBOX_START_ERROR",
            Error::SandboxStop(_) => "SANDBOX_STOP_ERROR",
            Error::SandboxExecution(_) => "SANDBOX_EXECUTION_ERROR",
            Error::SandboxNotFound(_) => "SANDBOX_NOT_FOUND",
            Error::InsufficientResources(_) => "INSUFFICIENT_RESOURCES",
            Error::PoolError(_) => "POOL_ERROR",
            Error::SchedulerError(_) => "SCHEDULER_ERROR",
            Error::MonitoringError(_) => "MONITORING_ERROR",
            Error::Network(_) => "NETWORK_ERROR",
            Error::Prometheus(_) => "PROMETHEUS_ERROR",
            Error::Utf8(_) => "UTF8_ERROR",
            Error::Timeout(_) => "TIMEOUT_ERROR",
            Error::PermissionDenied(_) => "PERMISSION_DENIED",
            Error::SystemCall(_) => "SYSTEM_CALL_ERROR",
            Error::Firecracker(_) => "FIRECRACKER_ERROR",
            Error::Internal(_) => "INTERNAL_ERROR",
            Error::Generic(_) => "GENERIC_ERROR",
            Error::Api(_) => "API_ERROR",
            Error::Validation(_) => "VALIDATION_ERROR",
        }
    }
}

/// 错误上下文trait，用于添加错误上下文信息
pub trait ErrorContext<T> {
    fn with_context<F>(self, f: F) -> Result<T>
    where
        F: FnOnce() -> String;
        
    fn context<S: Into<String>>(self, msg: S) -> Result<T>;
}

impl<T, E> ErrorContext<T> for std::result::Result<T, E>
where
    E: Into<Error>,
{
    fn with_context<F>(self, f: F) -> Result<T>
    where
        F: FnOnce() -> String,
    {
        self.map_err(|e| {
            let base_error = e.into();
            Error::Internal(format!("{}: {}", f(), base_error))
        })
    }
    
    fn context<S: Into<String>>(self, msg: S) -> Result<T> {
        self.with_context(|| msg.into())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_error_creation() {
        let err = Error::sandbox_creation("failed to create VM");
        assert!(matches!(err, Error::SandboxCreation(_)));
        assert_eq!(err.error_code(), "SANDBOX_CREATION_ERROR");
    }
    
    #[test]
    fn test_error_retryable() {
        let timeout_err = Error::timeout("operation timed out");
        assert!(timeout_err.is_retryable());
        
        let config_err = Error::ConfigFormat;
        assert!(!config_err.is_retryable());
    }
    
    #[test]
    fn test_error_context() {
        let result: Result<()> = Err(Error::sandbox_creation("VM creation failed"));
        let contextualized = result.context("during sandbox initialization");
        
        assert!(contextualized.is_err());
        assert!(contextualized.unwrap_err().to_string().contains("during sandbox initialization"));
    }
    
    #[test]
    fn test_error_display() {
        let err = Error::sandbox_not_found("sandbox-123");
        assert_eq!(err.to_string(), "Sandbox not found: sandbox-123");
    }
}